﻿namespace MvcScriptManager.UniqueKeyEncoding
{
    using System;
    using System.Globalization;
    using System.Text;
    using System.Web;

    /// <summary>
    /// Class to handle creating unique keys for ScriptManager files using a two-way
    /// scheme based on filename and script reference properties.
    /// </summary>
    public class UniqueKeyTwoWayEncoding : IUniqueKeyEncoder
    {
        /// <summary>
        /// Creates the unique key from the ScriptReference
        /// </summary>
        /// <param name="reference">The <see cref="ScriptReference"/></param>
        /// <param name="context">The HttpContext for the current request</param>
        /// <returns>The unique key for the file</returns>
        public string EncodeUniqueKey(ScriptReference reference, HttpContext context)
        {
            string baseString = string.Format(
                CultureInfo.InvariantCulture,
                "{0}|{1}|{2}|{3}|{4}",
                reference.GetUrl(context, true),
                reference.EnableCrunching ? "Y" : "N",
                reference.ResourceAssembly,
                reference.ResourceName,
                reference.ResourceTypeName);

            string encodedString = Convert.ToBase64String(Encoding.ASCII.GetBytes(baseString));

            return encodedString;
        }

        /// <summary>
        /// Rebuilds the ScriptReference object from a unique key
        /// </summary>
        /// <param name="uniqueKey">The unique key for the file</param>
        /// <param name="context">The HttpContext for the current request</param>
        /// <returns>The <see cref="ScriptReference"/></returns>
        public ScriptReference DecodeUniqueKey(string uniqueKey, HttpContext context)
        {
            string plainString = Encoding.ASCII.GetString(Convert.FromBase64String(uniqueKey));

            string[] scriptKeyParts = plainString.Split('|');

            ScriptReference reference = new ScriptReference(scriptKeyParts[0])
            {
                EnableCrunching = scriptKeyParts[1] == "Y",
                ResourceAssembly = scriptKeyParts[2],
                ResourceName = scriptKeyParts[3],
                ResourceTypeName = scriptKeyParts[4],
            };

            return reference;
        }
    }
}
